/**
  ******************************************************************************
  * @file    mg_test_ble.c
  * @author  
  * @version V1.1
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2020 Shanghai Macrogiga Electronics</center></h2>
  *
  ******************************************************************************
  */
#include <stdio.h>
#include "mg_driver.h"
#include "mg_ble_control.h"
#include "Config.h"


unsigned char UseUart = 0;
unsigned char AtcmdFlag = 0;
unsigned char SleepStop = 0x00; //0-no sleep, 1-sleep
unsigned int StandbyTick = 0;
u8 *ble_addr;

extern void UsrProcCallback(u8 evt, u8* contxt);
extern char GetConnectedStatus(void);

void toggle_led_io(void)
{
    static u8 high = 0;
    
    if(high)GPIO->DATA_OUT_SET = GPIO_PIN_10;
    else GPIO->DATA_OUT_CLEAR = GPIO_PIN_10;
    
    high = !high;
}

void led_io_init(void)
{
    GPIO_InitTypeDef cfg;
    
    GPIO_FunctionSelect(GPIO_MAP_PIN_A10,GPIO_MAP_PIN_FUNC3);
    
    cfg.GPIO_Mode = GPIO_Mode_Out_PP;
    cfg.GPIO_Pin  = GPIO_PIN_10;
    GPIO_Init(GPIO, &cfg);
    
    GPIO->DATA_OUT_CLEAR = GPIO_PIN_10;
}

void key_io_init(void)
{
    GPIO_InitTypeDef cfg;
    
    GPIO_FunctionSelect(GPIO_MAP_PIN_A0,GPIO_MAP_PIN_FUNC1);
    
    cfg.GPIO_Mode = GPIO_Mode_IPD;
    cfg.GPIO_Pin  = GPIO_PIN_0;
    GPIO_Init(GPIO, &cfg);
}

void PortSelIOInit(void)
{
    GPIO_InitTypeDef cfg;
    
    //Port select   
    GPIO_FunctionSelect(PORT_MAP,PORT_FUN);
    cfg.GPIO_Mode = GPIO_Mode_IPU;
    cfg.GPIO_Pin  = PORT_PIN;
    GPIO_Init(GPIO, &cfg);
    
    if (GPIO_ReadInputDataBit(GPIO, PORT_PIN))
    {
        UseUart = 1;
    }
}

void UART_Init(void)
{
    GPIO_InitTypeDef cfg;
    
    //BAUD
    GPIO_FunctionSelect(BAUD_MAP,BAUD_FUN);    
    cfg.GPIO_Mode = GPIO_Mode_IPU;
    cfg.GPIO_Pin  = BAUD_PIN;
    GPIO_Init(GPIO, &cfg);
    
    if (GPIO_ReadInputDataBit(GPIO, BAUD_PIN))
    {
        UART_Set_baudrate(115200);
    }
    else
    {
        UART_Set_baudrate(9600);
    }
    
    NVIC_EnableIRQ(INT_MASK_BIT_UART);
    
    //ATMODE
    GPIO_FunctionSelect(ATMODE_MAP,ATMODE_FUN);
    cfg.GPIO_Mode = GPIO_Mode_IPU;
    cfg.GPIO_Pin  = ATMODE_PIN;
    GPIO_Init(GPIO, &cfg);
    
    AtcmdFlag = GPIO_ReadInputDataBit(GPIO,ATMODE_PIN);
}

static void StatusIOInit(void)
{
    GPIO_InitTypeDef cfg;
    
    //CONN
    GPIO_FunctionSelect(CONN_MAP,CONN_FUN);
    cfg.GPIO_Mode = GPIO_Mode_Out_PP;
    cfg.GPIO_Pin  = CONN_PIN;
    GPIO_Init(GPIO, &cfg);
    
    GPIO_ResetBits(GPIO,CONN_PIN);
    
    //STANDBY
    GPIO_FunctionSelect(STANDBY_MAP,STANDBY_FUN);
    cfg.GPIO_Mode = GPIO_Mode_Out_PP;
    cfg.GPIO_Pin  = STANDBY_PIN;
    GPIO_Init(GPIO, &cfg);
    
    GPIO_SetBits(GPIO,STANDBY_PIN);
}



void I2C_SlaveInit(void)
{
    I2C_TypeInitDef I2C_InitStruct;
        
    I2C_InitStruct.I2C_Mode = I2C_MODE_SLAVE;
    I2C_InitStruct.I2C_Addr = 0x50;
    I2C_InitStruct.I2C_Speed = I2C_SPEED_STANDARD;
    I2C_Init(&I2C_InitStruct);
    I2C_Cmd(ENABLE);
    
    I2C_ITConfig(I2C_RD_REQ | I2C_RX_FULL | I2C_RX_DONE,ENABLE);
    NVIC_EnableIRQ(INT_MASK_BIT_IIC);
}

u8 Adv_Dat[31]={2,1,6},Adv_Len=3;
u8 Rsp_Dat[31]= {12,9,'M','G','1','7','5','1','-','U','A','R','T'},Rsp_Len=13;
u8 Adv_Type=0x40;
u16 Adv_Interval=160*2;
////// !!! porting function, this will be invoked by ble lib. !!!/////
void slave_app_cfg(void)
{
    BLE_ADV_DATA_INFO slave_cfg;
    
    slave_cfg.advType = Adv_Type & 0x0f;//ADV_NONCONN_IND;//ADV_IND;//ADV_SCAN_IND//ADV_DIRECT_IND
    slave_cfg.advData = Adv_Dat;
    slave_cfg.advDataLen = Adv_Len;    
    slave_cfg.scanResponseData= Rsp_Dat;    
    slave_cfg.scanResponseDataLen = Rsp_Len;
    slave_cfg.interval = Adv_Interval;
    slave_cfg.txAddrType = Adv_Type&0x40?ADDR_TYPE_RANDOM:0;
    slave_cfg.directIndTargetAddr[0] = 0xaa; //target addr if any
    slave_cfg.directIndTargetAddr[1] = 0xbb;
    slave_cfg.directIndTargetAddrType = 1;

    MgBle_Periph_Init(&slave_cfg);
}

void test_ble_stack_slave(void)
{
    GPIO_InitTypeDef cfg;
    
    led_io_init(); //debug purpose ONLY
    
    PortSelIOInit();
    if (UseUart)
    {
        UART_Init();
        
        //WAKEUP
        GPIO_FunctionSelect(GPIO_MAP_PIN_A2, GPIO_MAP_PIN_FUNC3);    
        cfg.GPIO_Mode = GPIO_Mode_IPU;
        cfg.GPIO_Pin  = GPIO_PIN_2;
        GPIO_Init(GPIO, &cfg);
        if(0 == AtcmdFlag)
        {
            if(Bit_RESET == GPIO_ReadInputDataBit(GPIO, GPIO_PIN_2))
                SleepStop = 1;
        }
        
        //REQ
        GPIO_FunctionSelect(GPIO_MAP_PIN_A1, GPIO_MAP_PIN_FUNC3);    
        cfg.GPIO_Mode = GPIO_Mode_IPU;
        cfg.GPIO_Pin  = GPIO_PIN_1;
        GPIO_Init(GPIO, &cfg);
        GPIO_ResetBits(GPIO,GPIO_PIN_1); 
    }
    else
    {
        I2C_SlaveInit();

        //WAKEUP
        GPIO_FunctionSelect(GPIO_MAP_PIN_A6, GPIO_MAP_PIN_FUNC3);    
        cfg.GPIO_Mode = GPIO_Mode_IPU;
        cfg.GPIO_Pin  = GPIO_PIN_6;
        GPIO_Init(GPIO, &cfg);
        if(Bit_RESET == GPIO_ReadInputDataBit(GPIO, GPIO_PIN_6))
            SleepStop = 1;

        //REQ
        GPIO_FunctionSelect(GPIO_MAP_PIN_A5,GPIO_MAP_PIN_FUNC3);
        cfg.GPIO_Mode = GPIO_Mode_Out_PP;
        cfg.GPIO_Pin  = GPIO_PIN_5;
        GPIO_Init(GPIO, &cfg);
        GPIO_ResetBits(GPIO,GPIO_PIN_5);
    }
    
    StatusIOInit();
    
    //================== BLE Base band init ================
    MgBle_Init(TXPWR_0DBM, &ble_addr);//

    //MgBle_SetBleAddr(ble_addr_set, 0); //set before slave_app_cfg()

//    MgBle_SetFixAdvChannel(1);
    
    //============ clear MCU pending irq if any ============
    NVIC_IrqClearPendingIRQ(BBSeg_IRQn);
    NVIC_IrqClearPendingIRQ(BB_IRQn);
    
    //============== Enable NVIC IRQ bits ==================
    NVIC_EnableIRQ(INT_MASK_BIT_BB_SEG);
    NVIC_EnableIRQ(INT_MASK_BIT_BB);
    
    //================== BLE Slave role init ===============
    slave_app_cfg(); //cfg the slave
    //================ BLE Slave stack running =============
    while(1)
    {
        //*** user task inserted here ***
        //to do...
        
        if (1||(0xffffffff == StandbyTick))
        {
            if ((StandbyTick > 5000)&&(StandbyTick < 0xffffffff))
            {
                StandbyTick = 0xffffffff;
                //radio_standby();
                MgBle_SetAdvEnable(0);
                GPIO_ResetBits(GPIO,STANDBY_PIN);
            }
            
            if (SleepStop)
            {
                SysGotoSleepMode();
            }
        }
        
        if (0 == MgBle_GetAdvEnable())
        {
            UsrProcCallback(0,NULL);
        }
    }
    
    //never be here
}

void SysTick_Handler(void)
{
    if(AtcmdFlag) return; //under ATcmd mode, don't use WAKEUP_PIN.
    if (0 == GetConnectedStatus())
    {
        if( ((UseUart)&&(Bit_RESET == GPIO_ReadInputDataBit(GPIO, GPIO_PIN_2)))
          ||((UseUart==0)&&(Bit_RESET == GPIO_ReadInputDataBit(GPIO, GPIO_PIN_6))) )
        {
            if (StandbyTick < 0xffffffff)
                StandbyTick ++;
        }
    }
    else
    {
        if (0xffffffff == StandbyTick)
        {
            //radio_resume();
            MgBle_SetAdvEnable(1);
            GPIO_SetBits(GPIO,STANDBY_PIN);
        }
        StandbyTick = 0;
    }
}
